// Global namespace
var MasterStroke = MasterStroke || {};

define
(
    ["require",
     "lib/knockout",
     "Common/OrderedChangeIdSet",
     "./Frame", 
     "./Types"],
    function (require, 
                  ko,
                  OrderedChangeIdSet,
                  Frame,
                  Types)
    {
        MasterStroke.Task = function (changeId, name, description)
        {
            var _that = this;
            this.changeId = changeId;
            this.name = name;
            this.description = description;
            var _frames = new OrderedChangeIdSet();
            this.frames = ko.observableArray(_frames.bindingSource());
            this.selectedFrame = ko.observable();
            
            this.addFrame = function(predecessorFrameId, frame)
            {
                if (!(frame instanceof MasterStroke.Frame))
                {
                    throw "frame must be a MasterStroke.Frame object";
                }

                _frames.add(predecessorFrameId, frame);
                this.frames.valueHasMutated();
            };

            this.getFrame = function(changeId)
            {
                return _frames.find(changeId);
            };

            this.deleteFrame = function(changeId)
            {
                var frame = this.getFrame(changeId);
                var frames = this.frames();
                var frameIndex = frames.indexOf(frame);
                _frames.delete(changeId);

                if (frame == this.selectedFrame())
                {
                    if (!frames.length)
                    {
                        this.selectedFrame(null);
                    }
                    else
                    {
                        if (frameIndex < frames.length)
                        {
                            this.selectedFrame(frames[frameIndex]);
                        }
                        else
                        {
                            this.selectedFrame(frames[frameIndex - 1]);
                        }
                    }
                }

                deleteFrameReferences(changeId);

                this.frames.valueHasMutated();
            };

            this.updateFrameChangeId = function(frame, newChangeId)
            {
                _frames.updateChangeId(frame, newChangeId);
            };

            this.reorderFrame = function(frameChangeId, newIndex)
            {
                _frames.reorderObject(frameChangeId, newIndex);
                this.frames.valueHasMutated();
            };

            function deleteFrameReferences(referenceFrameChangeId)
            {
                var frames = _that.frames();

                for (var i = 0; i < frames.length; i++)
                {
                    frames[i].removeReferenceFrame(referenceFrameChangeId);
                }
            }
        };

        return MasterStroke.Task;
    }
);